package com.ming.shiro;

import com.ming.entity.TbUser;
import com.ming.service.TbFunctionService;
import com.ming.service.TbRoleService;
import com.ming.service.TbUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collection;
import java.util.Set;

/**
 * @author MING
 * @date 2018/9/5 16:43
 */
public class CustomRealm extends AuthorizingRealm {
    @Autowired
    private TbUserService tbUserService;
    @Autowired
    private TbRoleService tbRoleService;
    @Autowired
    private TbFunctionService tbFunctionService;

    /**
     * 授权,设置权限角色
     * @param principalCollection  认证信息
     * @return
     */
    @Override
    public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("我在查询角色权限！");
//        从认证信息中获取到用户
        String name = (String) principalCollection.getPrimaryPrincipal();
//        获取到角色数据
        Set<String> role = tbRoleService.getRole(name);
        if (role.size() < 1){
            return null;
        }
//        获取到权限数据
        Set<String> function = tbFunctionService.getFunction(role);
        if (function.size() < 1){
            return null;
        }
//        将角色权限数据返回
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setRoles(role);
        simpleAuthorizationInfo.setStringPermissions(function);
        return simpleAuthorizationInfo;
    }

    /**
     * 认证,登录
     * @param authenticationToken  主体传递过来的认证信息
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException{
//        从主体传递过来的认证信息中获得用户名
        String name = (String) authenticationToken.getPrincipal();
//        通过用户名查询密码
        TbUser tbUser = tbUserService.login(name);
        if (tbUser == null){
            return null;
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                tbUser.getUserName(), tbUser.getUserPassword(), getName()
        );
        return authenticationInfo;
    }

    /**
     * 清空当前用户权限信息
     */
    public  void clearCachedAuthorizationInfo() {
        PrincipalCollection principalCollection = SecurityUtils.getSubject().getPrincipals();
        SimplePrincipalCollection principals = new SimplePrincipalCollection(
                principalCollection, getName());
        super.clearCachedAuthorizationInfo(principals);
    }

    /**
     * 获取用户角色
     * @return
     */
    public Collection<String> getRoles(){
//        getAuthorizationInfo会有限从缓存中获取，doGetAuthorizationInfo会从数据库中获取
        AuthorizationInfo authorizationInfo = getAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
        Collection<String> roles = authorizationInfo.getRoles();
        return roles;
    }

    /**
     * 获取用户权限
     * @return
     */
    public Collection<String> getFunction(){
//        getAuthorizationInfo会有限从缓存中获取，doGetAuthorizationInfo会从数据库中获取
        AuthorizationInfo authorizationInfo = getAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
        Collection<String> function = authorizationInfo.getStringPermissions();
        return function;
    }

    /**
     * 指定 principalCollection 清除
     * @param principalCollection
     */
    public void clearCachedAuthorizationInfo(PrincipalCollection principalCollection) {
        SimplePrincipalCollection principals = new SimplePrincipalCollection(
                principalCollection, getName());
        super.clearCachedAuthorizationInfo(principals);
    }
}
